﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bioinformatics.Types;
using Bioinformatics.Utilities;

namespace Bioinformatics.Algorithms
{
    public class PsomlNative : Psoml
    {
        public PsomlNative()
        {
            AlgorithmName = "PSOML Host Native";
        }

        public override void AutoRun()
        {
            //initialize swarm
            for (var i = 0; i < Swarm.Length; i++)
                Swarm[i] = new Particle(Phylogeny, LengthMax, LengthMin, LengthDeltaMax, LengthDeltaMin, Swarm.Length, NeighborhoodSize);

            for(var i = 0; i < GenerationMax; i++)
            {
                //calculate likelihood for all particles in swarm
                for(var s = 0; s < Swarm.Length; s++)
                    Swarm[s].CalculateLikelihood();
                //sort the array by likelihood - find global best
                Array.Sort(Swarm,Particle.Comparer);
                Array.Copy(Swarm[0].BranchLengths, Particle.BranchLengthGlobalBest, Swarm[0].BranchLengths.Length);
                //update local best
                for (var s = 0; s < Swarm.Length; s++)
                {
                    var nMax = 0;
                    for(var n = 0; n < Swarm[s].Neighbourhood.Length; n++)
                        if(Swarm[n].Likelihood > Swarm[nMax].Likelihood)
                            nMax = n;
                    Array.Copy(Swarm[nMax].BranchLengths, Swarm[s].BranchLengthsNeighbourhoodBest,
                               Swarm[nMax].BranchLengths.Length);
                }
                //adjust the velocities of each particle
                for (var s = 0; s < Swarm.Length; s++)
                    Swarm[s].AdjustVelocities();
                //update the position of each particle in the swarm
                for(var s = 0; s < Swarm.Length; s++)
                    Swarm[s].UpdateBranchLengths();
            }
        }
    }
}